package sivan.lock;

import org.junit.Test;
import org.openjdk.jol.info.ClassLayout;
import sivan.domain.User;

import java.util.concurrent.locks.ReentrantLock;

/**
 * java对象头信息包含：mark word和klasspointer两部分,数组则还要加上数组长度，即三部分组成。
 *
 * @Author : xiaowen
 * @create: 2020-07-18 11:40
 */
public class ObjectInfo {


    private int age;
    private long a;
    private double d;
    private char c;
    private String aa;
    private boolean b;
    private float f;
    private byte aByte;
    private short aShort;

    /**
     *
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Object user = new Object();
        System.out.println(ClassLayout.parseInstance(user).toPrintable());
        Thread thread1 = new Thread(() -> {
            synchronized (user) {
                System.out.println(Thread.currentThread() + "==" + ClassLayout.parseInstance(user).toPrintable());
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"线程1");

        Thread thread2 = new Thread(() -> {
            synchronized (user) {
                System.out.println(Thread.currentThread() + "==" + ClassLayout.parseInstance(user).toPrintable());
            }
        },"线程2");

        thread1.start();
        thread1.join();
        System.out.println(ClassLayout.parseInstance(user).toPrintable());
        thread2.start();
        thread2.join();
        System.out.println(ClassLayout.parseInstance(user).toPrintable());
    }

    @Test
    public void test() {
        ObjectInfo user = new ObjectInfo();
        user.setAge(111);
        user.setA(2L);
        user.setAa("xiaowen");
        user.setaByte((byte) 1);
        user.setaShort((short) 1);
        user.setB(false);
        user.setC('c');
        user.setD(11111);
        user.setF(111);
        ReentrantLock lock = new ReentrantLock();
        lock.lock();
        Thread thread1 = new Thread() {
            @Override
            public void run() {
                synchronized (user) {
                    System.out.println("线程1");
                    System.out.println(user.hashCode());
                    System.out.println(ClassLayout.parseInstance(user).toPrintable());
                }

                System.out.println("线程1#####");
                System.out.println(ClassLayout.parseInstance(user).toPrintable());
                try {
                    //thread1退出同步代码块，且没有死亡
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread thread2 = new Thread() {
            @Override
            public void run() {
                synchronized (user) {
                    System.out.println("线程2");
                    System.out.println(ClassLayout.parseInstance(user).toPrintable());
                }

                System.out.println("线程2#####");
                System.out.println(ClassLayout.parseInstance(user).toPrintable());
                try {
                    //thread1退出同步代码块，且没有死亡
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        thread1.start();
        thread2.start();
        lock.unlock();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public long getA() {
        return a;
    }

    public void setA(long a) {
        this.a = a;
    }

    public double getD() {
        return d;
    }

    public void setD(double d) {
        this.d = d;
    }

    public char getC() {
        return c;
    }

    public void setC(char c) {
        this.c = c;
    }

    public String getAa() {
        return aa;
    }

    public void setAa(String aa) {
        this.aa = aa;
    }

    public boolean isB() {
        return b;
    }

    public void setB(boolean b) {
        this.b = b;
    }

    public float getF() {
        return f;
    }

    public void setF(float f) {
        this.f = f;
    }

    public byte getaByte() {
        return aByte;
    }

    public void setaByte(byte aByte) {
        this.aByte = aByte;
    }

    public short getaShort() {
        return aShort;
    }

    public void setaShort(short aShort) {
        this.aShort = aShort;
    }
}
